package cn.hill4j.tool.spring.ext.dispatcher;

import cn.hill4j.tool.spring.ext.dispatcher.exception.DispatchInvokerException;

/**
 * 分发执行器
 * @param <R> 分发业务数据
 * @param <C> 分发内容上下文
 *
 * @author: hillchen
 * Date: 2023-02-17 14:46
 */
public interface Dispatcher<R,C extends DispatcherContext> {
    /**
     * @author hillchen
     * Description: 执行分发
     * Date 2023/8/8 23:40
     * @param requestData 请求参数
     * @return Object
     * @throws DispatchInvokerException 请求分发异常
     **/
    default Object dispatch(R requestData) throws DispatchInvokerException {
        // 将请求参数解析出context
        C context = resolveContext(requestData);
        // 获取路由标示
        DispatchRoute route = route(requestData,context);
        // 解析出请求参数
        Object[] args = resolveArgs(requestData,context);
        // 请求分发
        DsMethodHandler dsMethodHandler = DestinationFactory.selectHandler(route);
        return dsMethodHandler.invoke(args);
    }
    /**
     * @author hillchen
     * Description: 根据分发业务数据和分发上下文获取分发路由信息
     * Date 2023/8/8 23:42
     * @param requestData 分发业务数据
     * @param context 分发上下文
     * @return DispatchRoute
     **/
    DispatchRoute route(R requestData,C context);
    /**
     * @author hillchen
     * Description: 根据分发业务数据构建分发上下文
     * Date 2023/8/8 23:43
     * @param requestData 分发业务数据
     * @return C 分发上下文
     **/
    C resolveContext(R requestData);
    /**
     * @author hillchen
     * Description: 根据分发业务数据和分发上下文获解析出请求参数
     * Date 2023/8/8 23:43
     * @param requestData 分发业务数据
     * @param context 分发上下文
     * @return Object[]
     **/
    Object[] resolveArgs(R requestData,C context);
}
